package com.sf.fy.uav.applet.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sf.fy.uav.common.enums.ServicePrefixEnum;
import com.sf.fy.uav.common.response.user.UserCompanyResponse;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.RedisPrefixKey;
import com.sf.fy.uav.user.controller.UserCompanyRest;
import com.sf.fy.uav.user.entity.UserCompany;
import com.sf.fy.uav.common.awt.JwtUtil;
import com.sf.fy.uav.applet.login.service.LoginService;
import com.sf.fy.uav.common.enums.PlatformCodeEnum;
import com.sf.fy.uav.common.enums.UserStatusEnum;
import com.sf.fy.uav.common.response.login.LoginResponse;
import com.sf.fy.uav.common.utils.PhoneEncoderUtil;
import com.sf.fy.uav.user.entity.User;
import com.sf.fy.uav.user.entity.UserExtra;
import com.sf.fy.uav.user.mapper.UserExtraMapper;
import com.sf.fy.uav.user.rest.UserRest;
import com.sf.fy.uav.user.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * @author LTQ
 */
@Service
public class LoginServiceImpl implements LoginService {


    private final static Logger logger = LoggerFactory.getLogger(LoginServiceImpl.class);

    //沙盒测试
    private static final String url_sandbox = "https://api.weixin.qq.com/sns/jscode2session";


    @Autowired
    private RestTemplate restTemplate;


    @Value("${proxy-url:sfproxy.intsit.sfcloud.local}")
    private String proxyUrl;

    @Value("${sms.login-minute-limit: 5}")
    private Integer loginMinuteLimit;

    @Value("${is-use-proxy:false}")
    private boolean isUseProxy;

    @Value("${encrypt.config-env:test}")
    private String encryptConfigEnv;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PhoneEncoderUtil phoneEncoderUtil;

    @Autowired
    private UserRest userRest;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private UserExtraMapper userExtraMapper;

    @Autowired
    private UserCompanyRest userCompanyRest;


    @Override
    public String register(String phoneNumber) {
        String countryCode = "86";
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        String encryptPhone = phoneEncoderUtil.encryptString(phoneNumber);
        userQueryWrapper.eq("phone_number", encryptPhone);
        User user = userRest.getOne(encryptPhone, countryCode, PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
        if (ObjectUtils.isEmpty(user)) {
            Date date = new Date();
            user = new User();
            user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            user.setPhoneNumber(phoneNumber);
            user.setCountryCode(countryCode);
            user.setAvatar("");
            user.setPlatformCode(PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
            user.setStatus(UserStatusEnum.NORMAL.getValue());
            user.setCreateTime(date);
            user.setUpdateTime(date);
            iUserService.insert(user);
            UserExtra userExtra = new UserExtra();
            userExtra.setCreateTime(date);
            userExtra.setUpdateTime(date);
            userExtra.setUserId(user.getId());
            userExtra.setLastLoginTime(date);
            userExtraMapper.insert(userExtra);
        } else {
            throw new RuntimeException("当前账户已注册，请直接登录。");
        }
        String userId = user.getId();
        //准备存放在IWT中的自定义数据
        Map<String, Object> info = new HashMap<>(2);
        info.put("phone_number", phoneNumber);
        info.put("country_code", countryCode);
        //生成JWT字符串
        String token = JwtUtil.sign(userId, info);
        logger.info("### 登录成功, token={} ###", token);
//        iUserService.dealLogin(date, userId);
        return token;
    }

    @Override
    public Boolean checkCode(String code, String phoneNumber) {
        if (!"test".equals(encryptConfigEnv)) {
            Calendar calendar = Calendar.getInstance();
            //五分钟内登录
            calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - loginMinuteLimit);
            Long fiveMinuteAgo = calendar.getTimeInMillis();
            Set<String> set = redisTemplate.opsForZSet().rangeByScore(ServicePrefixEnum.MONTHLY_SETTLEMENT_PLATFORM + RedisPrefixKey.APPLET_PHONE_CODE_COUNT_DOWN + phoneNumber, fiveMinuteAgo, System.currentTimeMillis());
            if (!set.contains(code)) {
                return false;
            }
            String phoneCode = (String) redisTemplate.opsForValue().get(ServicePrefixEnum.MONTHLY_SETTLEMENT_PLATFORM + RedisPrefixKey.APPLET_PHONE_CODE + phoneNumber);
            if (!code.equals(phoneCode)) {
                return false;
            } else {
                redisTemplate.delete(ServicePrefixEnum.MONTHLY_SETTLEMENT_PLATFORM + RedisPrefixKey.APPLET_PHONE_CODE + phoneNumber);
            }
        }
        return true;
    }

    @Override
    public LoginResponse loginByPhoneNumber(String phoneNumber, String code) {
        Date date = new Date();
        LoginResponse loginResponse = new LoginResponse();
        String countryCode = "86";
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        String encryptPhone = phoneEncoderUtil.encryptString(phoneNumber);
        userQueryWrapper.eq("phone_number", encryptPhone);
        User user = userRest.getOne(encryptPhone, countryCode, PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
        if (ObjectUtils.isEmpty(user)) {
            throw new RuntimeException("当前账户未注册，请先注册。");
        }
        Boolean checkCode = checkCode(code, phoneNumber);
        if (!checkCode) {
            throw new RuntimeException("验证失败");
        }
        UserExtra userExtraOne = userExtraMapper.selectOne(new QueryWrapper<UserExtra>().eq("user_id", user.getId()));
        UserExtra userExtra = new UserExtra();
        userExtra.setUpdateTime(date);
        userExtra.setUserId(user.getId());
        userExtra.setLastLoginTime(date);
        if (!ObjectUtils.isEmpty(userExtraOne)) {
            userExtraMapper.update(userExtra, new UpdateWrapper<UserExtra>().eq("user_id", user.getId()));
        } else {
            userExtra.setCreateTime(date);
            userExtraMapper.insert(userExtra);
        }
        String userId = user.getId();
        //准备存放在IWT中的自定义数据
        Map<String, Object> info = new HashMap<>(2);
        info.put("phone_number", phoneNumber);
        info.put("country_code", countryCode);
        //生成JWT字符串
        String token = JwtUtil.sign(userId, info);
        loginResponse.setToken(token);
        loginResponse.setAvatar(user.getAvatar());
        loginResponse.setPhoneNumber(PhoneEncoderUtil.desensitization(phoneEncoderUtil.decryptString(user.getPhoneNumber())));
        //查看用户公司信息
        UserCompany userCompany = userCompanyRest.getByUserId(userId);
        UserCompanyResponse userCompanyResponse = BeanUtil.copyProperties(userCompany, UserCompanyResponse.class);
        loginResponse.setUserCompanyResponse(userCompanyResponse);
        return loginResponse;
    }

}
